/*
 * Copyright 2002-2021 the original author or authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      https://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package org.springframework.transaction.event;

import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

import org.springframework.context.event.EventListener;
import org.springframework.core.annotation.AliasFor;

/**
 *一个根据{@link TransactionPhase}被调用的{@link EventListener}。
 * 这是一个基于注解的{@link TransactionalApplicationListener}的等同物。
 *
 * 如果事件没有在一个活动的事务中发布，该事件将被丢弃除非{@link #fallbackExecution}标志被明确设置。
 * 如果一个事务正在运行，事件将根据其{@code TransactionPhase}来处理。
 *
 * 将{@link org.springframework.core.annotation.Order @Order}添加到你的注释方法中，允许你在事务完成之前或之后运行的其他监听器中优先考虑该监听器。
 *
 * 注意事项: 事务性事件监听器只对线程绑定的事务起作用由{@link org.springframework.transaction.PlatformTransactionManager}管理。
 * 由{@link org.springframework.transaction.ReactiveTransactionManager}管理的反应式事务使用Reactor上下文而不是线程本地属性，
 * 所以从事件监听器的角度来看事件监听器的角度来看，没有兼容的活动事务，它可以参与其中。
 *
 * @author Stephane Nicoll
 * @author Sam Brannen
 * @author Oliver Drotbohm
 * @since 4.2
 * @see TransactionalApplicationListener
 * @see TransactionalApplicationListenerMethodAdapter
 */
@Target({ElementType.METHOD, ElementType.ANNOTATION_TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@EventListener
public @interface TransactionalEventListener {

	/**
	 * 绑定事件处理的阶段。
	 * 默认阶段是{@link TransactionPhase#AFTER_COMMIT}。
	 * 如果没有事务正在进行中，该事件就不会被处理。
	 * 除非{@link #fallbackExecution}已经被明确启用。
	 */
	TransactionPhase phase() default TransactionPhase.AFTER_COMMIT;

	/**
	 * 如果没有事务正在运行，是否应该处理该事件。
	 */
	boolean fallbackExecution() default false;

	/**
	 * {@link #classes}的别名。
	 */
	@AliasFor(annotation = EventListener.class, attribute = "classes")
	Class<?>[] value() default {};

	/**
	 * 这个监听器所处理的事件类别。
	 * 如果这个属性被指定为一个单一的值，那么被注解的方法可以选择性地接受一个单一的参数。
	 * 然而，如果这个属性被指定为多个值，那么被注释的方法必须不声明任何参数。
	 */
	@AliasFor(annotation = EventListener.class, attribute = "classes")
	Class<?>[] classes() default {};

	/**
	 * Spring Expression Language (SpEL)属性用于使事件处理具有条件性。
	 * 默认是{@code ""}，意味着事件总是被处理。
	 * @see EventListener#condition
	 */
	@AliasFor(annotation = EventListener.class, attribute = "condition")
	String condition() default "";

	/**
	 * 倾听者的可选标识符，默认为声明方法的全称签名（例如 "mypackage.MyClass.myMethod()"）。
	 * @since 5.3
	 * @see EventListener#id
	 * @see TransactionalApplicationListener#getListenerId()
	 */
	@AliasFor(annotation = EventListener.class, attribute = "id")
	String id() default "";

}
